package com.nanyang.tms.service.bill.impl;

import cn.hutool.core.date.DateUtil;
import com.nanyang.common.core.dict.CommonEnum;
import com.nanyang.common.core.domain.ApiResult;
import com.nanyang.common.core.exception.ExceptionProcessorUtils;
import com.nanyang.common.core.flow.context.TransHandlerContext;
import com.nanyang.common.core.flow.invoker.TransOutboundInvoker;
import com.nanyang.common.core.page.PageBean;
import com.nanyang.common.core.page.PageTableBean;
import com.nanyang.common.tool.utils.convert.BeanUtils;
import com.nanyang.tms.api.dto.request.bill.*;
import com.nanyang.tms.api.dto.response.bill.BillPageResponse;
import com.nanyang.tms.api.dto.response.bill.BillRecordPageResponse;
import com.nanyang.tms.api.service.bill.BillRpcService;
import com.nanyang.tms.dao.bill.BillDao;
import com.nanyang.tms.dao.bill.BillRecordDao;
import com.nanyang.tms.domain.bill.*;
import com.nanyang.tms.manager.bill.BillManager;
import com.nanyang.tms.service.bill.impl.flow.BillProcessPipelineFactory;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service(version = "1.0.0", timeout = 10000, retries = 0, validation = "true")
public class BillRpcServiceImpl implements BillRpcService {
    @Autowired
    private BillManager billManager;
    @Autowired
    private BillProcessPipelineFactory billProcessPipelineFactory;
    @Autowired
    private BillRecordDao billRecordDao;
    @Autowired
    private BillDao billDao;
    @Override
    public ApiResult<PageBean<BillPageResponse>> listBill(BillQueryRequest param) {
        ApiResult<PageBean<BillPageResponse>> apiResult = new ApiResult<>();
        try {
            param.requestCheck();
            BillQuery query = new BillQuery();
            BeanUtils.copyProperties(param, query);
            PageBean<BillVO> billList = billManager.listBill(query);
            PageBean<BillPageResponse> resultList = new PageTableBean<>(query.getPageIndex(), query.getPageSize());
            resultList.setTotalItem(billList.getTotalItem());
            BeanUtils.copyListProperties(billList.getData(), resultList.getData(), BillPageResponse.class);
            apiResult.setCode(CommonEnum.REQUEST_SUCCESS.getCode());
            apiResult.setMessage(CommonEnum.REQUEST_SUCCESS.getMessage());
            apiResult.setData(resultList);
        } catch (Exception e) {
            log.error(CommonEnum.SYSTEM_EXCEPTION.getMessage(), e);
            ExceptionProcessorUtils.wrapperHandlerException(apiResult, e);
        }
        return apiResult;
    }

    @Override
    public ApiResult<PageBean<BillRecordPageResponse>> listBillRecord(BillRecordQueryRequest param) {
        ApiResult<PageBean<BillRecordPageResponse>> apiResult = new ApiResult<>();
        try {
            param.requestCheck();
            BillRecordQuery query = new BillRecordQuery();
            BeanUtils.copyProperties(param, query);
            PageBean<BillRecordVO> billRecordList = billManager.listBillRecord(query);
            PageBean<BillRecordPageResponse> resultList = new PageTableBean<>(query.getPageIndex(), query.getPageSize());
            resultList.setTotalItem(billRecordList.getTotalItem());
            BeanUtils.copyListProperties(billRecordList.getData(), resultList.getData(), BillRecordPageResponse.class);
            apiResult.setCode(CommonEnum.REQUEST_SUCCESS.getCode());
            apiResult.setMessage(CommonEnum.REQUEST_SUCCESS.getMessage());
            apiResult.setData(resultList);
        } catch (Exception e) {
            log.error(CommonEnum.SYSTEM_EXCEPTION.getMessage(), e);
            ExceptionProcessorUtils.wrapperHandlerException(apiResult, e);
        }
        return apiResult;
    }

    @Override
    public ApiResult<Boolean> addBill(BillAddRequest param) {
        ApiResult<Boolean> result = new ApiResult<>();
        try {
            param.requestCheck();
            BillDO billDO = new  BillDO();
            BeanUtils.copyProperties(param,billDO);
            billDO.setGmtCreatePin(param.getPin());
            billDO.setBillDate(DateUtil.parseDateTime(param.getBillDate()));
            billManager.addBill(billDO);
            result.setCode(CommonEnum.REQUEST_SUCCESS.getCode());
            result.setMessage(CommonEnum.REQUEST_SUCCESS.getMessage());
            result.setData(true);
        } catch (Exception e) {
            log.error(CommonEnum.SYSTEM_EXCEPTION.getMessage(), e);
            ExceptionProcessorUtils.wrapperHandlerException(result, e);
        }
        return result;
    }
    @Override
    public ApiResult<Boolean> checkBill(BillRecordUpdateRequest param){
        ApiResult<Boolean> result = new ApiResult<>();
        try {
            param.requestCheck();
            BillDO billDO = new  BillDO();
            BeanUtils.copyProperties(param,billDO);
            billDO.setGmtModifiedPin(param.getPin());
            billManager.checkBill(billDO);
            result.setCode(CommonEnum.REQUEST_SUCCESS.getCode());
            result.setMessage(CommonEnum.REQUEST_SUCCESS.getMessage());
            result.setData(true);
        } catch (Exception e) {
            log.error(CommonEnum.SYSTEM_EXCEPTION.getMessage(), e);
            ExceptionProcessorUtils.wrapperHandlerException(result, e);
        }
        return result;
    }
    @Override
    public ApiResult<Boolean> syncCheckBill(String billCode){
        ApiResult<Boolean> result = new ApiResult<>();
        try {
            billManager.syncCheckBill(billCode);
            result.setCode(CommonEnum.REQUEST_SUCCESS.getCode());
            result.setMessage(CommonEnum.REQUEST_SUCCESS.getMessage());
            result.setData(true);
        } catch (Exception e) {
            log.error(CommonEnum.SYSTEM_EXCEPTION.getMessage(), e);
            ExceptionProcessorUtils.wrapperHandlerException(result, e);
        }
        return result;
    }

    @Override
    public ApiResult<Boolean> solveBill(BillRecordUpdateRequest param){
        ApiResult<Boolean> result = new ApiResult<>();
        try {
            param.requestCheck();
            BillDO billDO = new  BillDO();
            BeanUtils.copyProperties(param,billDO);
            billDO.setGmtModifiedPin(param.getPin());
            billManager.solveBill(billDO);
            result.setCode(CommonEnum.REQUEST_SUCCESS.getCode());
            result.setMessage(CommonEnum.REQUEST_SUCCESS.getMessage());
            result.setData(true);
        } catch (Exception e) {
            log.error(CommonEnum.SYSTEM_EXCEPTION.getMessage(), e);
            ExceptionProcessorUtils.wrapperHandlerException(result, e);
        }
        return result;
    }
    @Override
    public ApiResult<Boolean> syncSolveBill(String billCode){
        ApiResult<Boolean> result = new ApiResult<>();
        try {
            List<BillRecordVO> billRecordVOS = billRecordDao.listRecordByBillCode(billCode);
            List<BillRecordDO> listBill=new ArrayList<>();
            for (BillRecordVO billRecordVO : billRecordVOS) {
                try {
                    BillSolveRequest billSolveRequest = new BillSolveRequest();
                    billSolveRequest.setBillRecordCode(billRecordVO.getBillRecordCode());
                    TransOutboundInvoker build = billProcessPipelineFactory.build(billSolveRequest);
                    build.start();
                    TransHandlerContext context = build.getContext();
                    log.info(context.toString());
                } catch (Exception e) {
                    log.error("处理差异异常："+billRecordVO.getBillRecordCode(), e);
                    BillRecordDO billRecordDO = new BillRecordDO();
                    billRecordDO.setIsDiff(2);//处理完成
                    billRecordDO.setBillRecordCode(billRecordVO.getBillRecordCode());
                    billRecordDO.setSolveResult(String.format(CommonEnum.SYSTEM_EXCEPTION.getMessage(),e.getMessage()));
                    listBill.add(billRecordDO);
                }
            }
            billManager.syncUpdateBill(listBill,billCode);
            result.setCode(CommonEnum.REQUEST_SUCCESS.getCode());
            result.setMessage(CommonEnum.REQUEST_SUCCESS.getMessage());
            result.setData(true);
        } catch (Exception e) {
            log.error(CommonEnum.SYSTEM_EXCEPTION.getMessage(), e);
            ExceptionProcessorUtils.wrapperHandlerException(result, e);
        }
        return result;
    }
}
